package com.zzc.emotisenseclassroom.domain.classScore.service.impl;

import com.alibaba.fastjson2.JSON;
import com.zzc.emotisenseclassroom.dbservice.EmotisenseScore.EmotisenseScoreDbService;
import com.zzc.emotisenseclassroom.domain.classScore.service.ClassScoreService;
import com.zzc.emotisenseclassroom.domain.classScore.dto.BarAndPieOptionRequestDTO;
import com.zzc.emotisenseclassroom.domain.classScore.dto.LineOptionRequestDTO;
import com.zzc.emotisenseclassroom.domain.classScore.vo.BarAndPieOptionVO;
import com.zzc.emotisenseclassroom.domain.classScore.vo.EmotiSenseScoreVO;
import com.zzc.emotisenseclassroom.domain.classScore.vo.LineOptionVO;
import com.zzc.emotisenseclassroom.domain.classScore.vo.optionComponet.*;
import com.zzc.emotisenseclassroom.utils.ConstantUtil;
import com.zzc.emotisenseclassroom.utils.DateUtil;
import com.zzc.utils.Verify;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Copyright Zzc
 * FileName: ClassScoreServiceImpl
 * Author:   Zzc
 * Date:     2024/5/313:18
 * Description: 班级课堂专注度评分业务层实现类
 * hISTORY:
 * <author>  <time>     <version>    <desc>
 * 作者姓名   修改时间       版本号       描述
 * Zzc                   1.0.0
 */
@Service
public class ClassScoreServiceImpl implements ClassScoreService {
    @Autowired
    private EmotisenseScoreDbService emotisenseScoreDbService;


    @Override
    public String getLineOption(LineOptionRequestDTO requestDTO) {
        LineOptionVO lineOptionVO = new LineOptionVO();
        Title title = new Title();
        title.setText("班级课堂专注度趋势变化图");
        lineOptionVO.setTitle(title);

        Tooltip tooltip = new Tooltip();
        lineOptionVO.setTooltip(tooltip);

        XAxis xAxis = new XAxis();
        xAxis.setName("时间");
        List<String> timeData = new ArrayList<>();
        xAxis.setData(timeData);
        lineOptionVO.setXAxis(xAxis);

        YAxis yaxis = new YAxis();
        lineOptionVO.setYAxis(yaxis);

        Legend legend = new Legend();
        legend.setData(List.of("平均分"));
        lineOptionVO.setLegend(legend);

        List<SeriesElement> list = new ArrayList<>(4);
        SeriesElement seriesElement = new SeriesElement();
        seriesElement.setName("平均分");
        List<Object> seriesList = new ArrayList<>();
        seriesElement.setData(seriesList);
        seriesElement.setType("line");
        seriesElement.setSmooth(true);
        list.add(seriesElement);
        lineOptionVO.setSeries(list);

        List<EmotiSenseScoreVO> classEmotisenseScoreList = emotisenseScoreDbService.getClassEmotisenseScore(
                DateUtil.removeTime(requestDTO.getDateBegin()), DateUtil.removeTime(requestDTO.getDateEnd()),
                requestDTO.getSchoolId(), requestDTO.getClassId());
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        // 将分数以日期分组
        Map<String, List<EmotiSenseScoreVO>> dateToScoreList = classEmotisenseScoreList.stream()
                .collect(Collectors.groupingBy(e ->dateFormat.format(e.getClassDate())));

        Date date = requestDTO.getDateBegin();
        double lastScore = !Verify.isEmpty(classEmotisenseScoreList) ? 91 : 0;

        do {
            timeData.add(dateFormat.format(date));

            List<EmotiSenseScoreVO> scoreList = dateToScoreList.get(dateFormat.format(date));

            if (!Verify.isEmpty(scoreList)){
                double averageScore = scoreList.stream()
                        .mapToDouble(a -> a.getScore() != null ? a.getScore() : 0) // 获取每个成绩
                        .average() // 计算平均值
                        .orElse(0.0); // 如果列表为空，默认返回 0.0
                seriesList.add(averageScore);

                lastScore = averageScore;
            }else {
                seriesList.add(lastScore);
            }

            date = new Date(date.getTime() + ConstantUtil.ONE_DAY_MILLIS);
        }while (date.compareTo(requestDTO.getDateEnd())<=0);

        DecimalFormat df = new DecimalFormat("#.00");

        // 遍历列表，格式化所有数据
        for (int i = 0; i < seriesList.size(); i++) {
            seriesList.set(i, Double.parseDouble(df.format(seriesList.get(i))));
        }

        SeriesElement seriesElement1 = new SeriesElement();
        List<Object> excellentLine = new ArrayList<>(seriesList.size());
        for (int i = 0; i < seriesList.size(); i++) {
            excellentLine.add(90);
        }
        seriesElement1.setData(excellentLine);

        SeriesElement seriesElement2 = new SeriesElement();
        List<Object> goodLine = new ArrayList<>(seriesList.size());
        for (int i = 0; i < seriesList.size(); i++) {
            goodLine.add(80);
        }
        seriesElement2.setData(goodLine);

        SeriesElement seriesElement3 = new SeriesElement();
        List<Object> averageLine = new ArrayList<>(seriesList.size());
        for (int i = 0; i < seriesList.size(); i++) {
            averageLine.add(60);
        }
        seriesElement3.setData(averageLine);

        list.addAll(Arrays.asList(seriesElement1, seriesElement2, seriesElement3));

        return JSON.toJSONString(lineOptionVO);
    }

    @Override
    public String getBarAndPieOption(BarAndPieOptionRequestDTO requestDTO) {
        BarAndPieOptionVO barAndPieOptionVO = new BarAndPieOptionVO();
        List<ValueAndName> list = new ArrayList<>(4);
        list.add(new ValueAndName(0, "优秀"));
        list.add(new ValueAndName(0, "良好"));
        list.add(new ValueAndName(0, "中等"));
        list.add(new ValueAndName(0, "较差"));
        barAndPieOptionVO.setPieOptionData(list);

        List<EmotiSenseScoreVO> classEmotisenseScoreList = emotisenseScoreDbService.getClassEmotisenseScore(
                DateUtil.removeTime(requestDTO.getDateBegin()), DateUtil.removeTime(requestDTO.getDateEnd()),
                requestDTO.getSchoolId(), requestDTO.getClassId());

        if (!Verify.isEmpty(classEmotisenseScoreList)){
            buildScoreCount(list, classEmotisenseScoreList);
        }

        barAndPieOptionVO.setBarOptionData(list.stream().map(ValueAndName::getValue).toList());
        return JSON.toJSONString(barAndPieOptionVO);
    }

    /**
     * 构建柱状图和饼状图数据
     * @param list
     * @param classEmotisenseScoreList
     */
    private void buildScoreCount(List<ValueAndName> list, List<EmotiSenseScoreVO> classEmotisenseScoreList) {
        // 将每个学生的成绩分组
        Map<Long, List<EmotiSenseScoreVO>> studentIdToScoreMap = classEmotisenseScoreList.stream()
                .collect(Collectors.groupingBy(EmotiSenseScoreVO::getUserId));

        studentIdToScoreMap.forEach((key, scoreList) -> {
            double averageScore = scoreList.stream()
                    .mapToDouble(a -> a.getScore() != null ? a.getScore() : 0) // 获取每个成绩
                    .average() // 计算平均值
                    .orElse(0.0); // 如果列表为空，默认返回 0.0

            if (averageScore >= 90) {
                list.get(0).setValue(list.get(0).getValue() + 1);
            } else if (averageScore >= 80) {
                list.get(1).setValue(list.get(1).getValue() + 1);
            } else if (averageScore >= 60) {
                list.get(2).setValue(list.get(2).getValue() + 1);
            } else if (averageScore >= 0) {
                list.get(3).setValue(list.get(3).getValue() + 1);
            }
        });
    }
}
